<!-- 新增弹窗 -->
<template>
  <el-dialog v-model="show" :title="title" destroy-on-close>
    <template #default>
      <el-form ref="myForm" label-width="100" :model="model" :rules="rules">
        <el-form-item label="节点类型" prop="type">
          <el-radio-group v-model="model.type">
            <el-radio :label="0">目录</el-radio>
            <el-radio :label="1">菜单</el-radio>
            <el-radio :label="2">按钮</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="节点名称" prop="name">
          <el-input v-model="model.name" placeholder="请填写节点名称" />
        </el-form-item>

        <el-form-item label="上级节点">
          <el-tree-select
            v-model="model.parentId"
            check-strictly
            :props="{
              label: 'name',
              value: 'id'
            }"
            :data="displayMenuList"
          />
        </el-form-item>

        <el-form-item label="节点路由">
          <el-input v-model="model.router" placeholder="请填写节点路由，如: /test" />
        </el-form-item>

        <el-form-item label="路由缓存">
          <el-radio-group v-model="model.keepAlive">
            <el-radio :label="true">开启</el-radio>
            <el-radio :label="false">关闭</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="是否显示">
          <el-switch v-model="model.isShow" />
        </el-form-item>

        <el-form-item label="文件路径">
          <el-input
            v-model="model.viewPath"
            placeholder="请填写文件路径，如: sys/menu-list/index.vue"
          />
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-space>
        <el-button type="default" @click="onCancel">取消</el-button>
        <el-button type="primary" @click="onConfrim">确认</el-button>
      </el-space>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { computed, reactive, ref } from 'vue'
import type { FormInstance } from 'element-plus'
import { addMenu, updateMenu } from '@/api/menu'

function deep(menus: IMenu[]) {
  return menus
    .filter((item) => item.type === 0)
    .map((item) => {
      // 避免修改到源数据
      const curItem = { ...item }
      if (curItem.children && curItem.children.length) {
        curItem.children = deep(curItem.children)
      }
      return curItem
    })
}

const props = defineProps<{
  menuList: IMenu[]
}>()

const emit = defineEmits(['success'])

// 上级节点，只能 type 为 目录的，才可以被选择，基于 props.menuList 做过滤
const displayMenuList = computed(() => {
  return deep(props.menuList)
})

const show = ref(false)
const title = ref('新增')

const id = ref()
// 表单数据
const model = reactive({
  type: 0,
  name: '',
  parentId: null as string | null,
  router: '',
  keepAlive: true,
  isShow: true,
  viewPath: ''
})

// 表单校验规则
const rules = {
  type: [{ required: true, message: '请选择节点类型' }],
  name: [{ required: true, message: '请填写节点名称' }]
}

const myForm = ref<FormInstance | null>(null)

// 取消方法
function onCancel() {
  // 关闭弹窗
  show.value = false
}

// 确认方法
async function onConfrim() {
  // 1. 表单校验
  await myForm.value?.validate()
  try {
    // 2. 判断 id 是否存在，来调用不同接口
    if (id.value) {
      // 编辑
      await updateMenu({ ...model, id: id.value })
    } else {
      // 新增
      await addMenu(model)
    }

    // 3. 告诉父组件我新增成功了，让父组件去更新数据，通过触发一个自定义事件
    emit('success')
    // 4. 关闭弹窗
    show.value = false
  } catch (error) {
    console.log('失败了')
  }
}

// 打开弹窗
function open(menu?: IMenu) {
  // 判断 menu 是否存在
  if (menu) {
    // 编辑操作
    title.value = '编辑'
    // 数据回填
    // model.type = menu.type
    // model.name = menu.name
    // ...
    // Object.assign(model, menu, {
    //   isShow: !!menu.isShow,
    //   keepAlive: !!menu.keepAlive
    // })
    id.value = menu.id
    model.type = menu.type
    model.name = menu.name
    model.parentId = menu.parentId
    model.router = menu.router as string
    model.keepAlive = !!menu.keepAlive
    model.isShow = !!menu.isShow
    model.viewPath = menu.viewPath as string
  } else {
    // 新增操作
    title.value = '新增'
    id.value = undefined
    // 清空数据
    Object.assign(model, {
      type: 0,
      name: '',
      parentId: null,
      router: '',
      keepAlive: true,
      isShow: true,
      viewPath: ''
    })
  }
  // 直接打开弹窗
  show.value = true
}

// 暴露一些内容给父组件
defineExpose({
  open
})
</script>
